package mail;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.Flags.Flag;

import mail.auth.CustomAuthenticator;

public class IMAPConnection {
	public static final String IMAP = "imap";
	public static final String IMAPS = "imaps";
	
	private Properties props;
	private Session session;
	private Store store;
	private CustomAuthenticator auth;
	
	public IMAPConnection(String name, String email, String password, boolean debug) throws NoSuchProviderException, BadProtocolException {
		this(IMAPS, "imap.gmail.com", 993, name, email, password, debug);
	}
	
	public IMAPConnection(String protocol, String host, int port, String name, String email, String password, boolean debug)
		throws BadProtocolException, NoSuchProviderException {
		if (!protocol.equals(IMAP) && !protocol.equals(IMAPS))
			throw new BadProtocolException("Protocol must be either IMAP or IMAPS");
		
		props = new Properties();
		props.setProperty("mail.store.protocol", protocol);
		props.setProperty("mail."+protocol+".host", host);
		props.setProperty("mail."+protocol+".port", port+"");
		auth = new CustomAuthenticator(name, email, password);
		
		session = Session.getInstance(props, auth);
		
		session.setDebug(debug);
		
		store = session.getStore();
	}
	
	public void connect() throws MessagingException { store.connect(); }
	public void disconnect() throws MessagingException { store.close(); }
	
	public Store getStore() { return store; }
	public CustomAuthenticator getAuthenticator() { return auth; }
	public String getProtocol() { return props.getProperty("mail.store.protocol"); }
	public String getHost() { return props.getProperty("mail."+getProtocol()+".host"); }
	public int getPort() { return new Integer(props.getProperty("mail."+getProtocol()+".port")); }
	
	
	public static void main(final String[] args) throws MessagingException, BadProtocolException {
		IMAPConnection conn = new IMAPConnection(UserInfo.name, UserInfo.email, UserInfo.password, false);
		conn.connect();
		conn.dumpFolder(conn.getStore().getDefaultFolder(), true, "");
		conn.disconnect();
    }
    
    private void dumpFolder(Folder folder, boolean recurse, String tab) throws MessagingException {
    	System.out.println(tab + "Name:      " + folder.getName());
    	System.out.println(tab + "Full Name: " + folder.getFullName());
    	System.out.println(tab + "URL:       " + folder.getURLName());

	    if (!folder.isSubscribed())
	    	System.out.println(tab + "Not Subscribed");

	    if ((folder.getType() & Folder.HOLDS_MESSAGES) != 0) {
	    	if (folder.hasNewMessages())
	    		System.out.println(tab + "Has New Messages");
		
			System.out.println(tab + "Total Messages:  " + folder.getMessageCount());
			System.out.println(tab + "New Messages:    " + folder.getNewMessageCount());
			System.out.println(tab + "Unread Messages: " + folder.getUnreadMessageCount());
			
			/*folder.open(Folder.READ_ONLY);
			int counter = 0;
		    for (Message msg : folder.getMessages()) {
		    	Flags flags = msg.getFlags();
		    	
		    	String status = (flags.contains(Flag.SEEN)) ? "OPENED" : "UNOPENED";
		    	
		    	System.out.println(tab + status + " | " + msg.getSubject() + " | " + msg.getReceivedDate().getTime());

		    	if (++counter > 5)
		    		break;
		    }
		    folder.close(false);*/
	    }

	    /*if (folder instanceof IMAPFolder) {
			IMAPFolder f = (IMAPFolder)folder;
			String[] attrs = f.getAttributes();
			if (attrs != null && attrs.length > 0) {
			    System.out.println(tab + "IMAP Attributes:");
			    for (int i = 0; i < attrs.length; i++)
				System.out.println(tab + "    " + attrs[i]);
			}
	    }*/
	
		System.out.println();
	
		if (recurse) {
			Folder[] f = folder.list();
			for (int i = 0; i < f.length; i++)
			    dumpFolder(f[i], true, tab + "    ");
		}
    }
}
